#include "../source/Server_version2.hpp"
#include <string>

void close_callback(muduo::Channel *channel)
{
    channel->Remove();
    ::close(channel->Fd()); // 这个时候不能直接关闭，因为read会开启写事件，如果close了，那么写事件就会出问题
    DBG_LOG("close fd: %d", channel->Fd());
    delete channel;
    return;
}

// 将数据读出，
// 疑问：为什么客户端退出时，监听写事件之前不去调用close_callback，而且没有调用到close_callback就析构了channel
void read_callback(muduo::Channel *channel)
{
    DBG_LOG("read_callback(muduo::Channel *channel)");
    int fd = channel->Fd();
    char buffer[1024];
    int ret = ::recv(fd, buffer, 1023, 0);
    if (ret <= 0)
    {
        close_callback(channel);
        return; // 添加return语句防止后续代码执行
    }
    buffer[ret] = 0;
    DBG_LOG("message: %s", buffer);
    channel->enAblewrite(); // 此时肯定有数据，开启写监控
    return;
}

void write_callback(muduo::Channel *channel)
{
    DBG_LOG("write_callback(muduo::Channel *channel)");
    std::string ss("今天天气真好");
    int fd = channel->Fd();
    int ret = ::send(fd, ss.c_str(), ss.size(), 0);
    if (ret < 0)
    {
        DBG_LOG("write_callback send error");
        close_callback(channel);
        return;
    }
    channel->disAblewrite();
    return;
}

void error_callback(muduo::Channel *channel)
{
    close_callback(channel);
    return;
}

void event_callback(muduo::EventLoop *Loop, muduo::Channel *channel, u_int64_t id)
{
    // DBG_LOG("channel sockfd: %d", channel->Fd());
    INF_LOG("event_callback(muduo::Channel *channel)");
    /// 进行定时任务的刷新
    Loop->TimerRefresh(id);
    return;
}

void Accept(muduo::EventLoop *Loop, muduo::Channel &channel)
{
    DBG_LOG("Accept new channel");
    u_int64_t id = rand() % 10000;
    int fd = channel.Fd();
    int newfd = ::accept(fd, nullptr, nullptr);
    muduo::Channel *newfd_channel = new muduo::Channel(Loop, newfd);
    newfd_channel->set_read_callback(std::bind(read_callback, newfd_channel));
    newfd_channel->set_write_callback(std::bind(write_callback, newfd_channel));
    newfd_channel->set_close_callback(std::bind(close_callback, newfd_channel));
    newfd_channel->set_error_callback(std::bind(error_callback, newfd_channel));
    newfd_channel->set_event_callback(std::bind(event_callback, Loop, newfd_channel, id));
    /// 开启定时任务
    Loop->TimerAdd(id, 10, std::bind(close_callback, newfd_channel));
    newfd_channel->enAbleread();
}
int main()
{
    // std::string ip = "127.0.0.1";
    srand(time(NULL));
    u_int16_t port = 9999;

    muduo::Socket listen_socket;
    listen_socket.CreateServer(port);
    muduo::EventLoop Loop;
    muduo::Channel channel(&Loop, listen_socket.Fd()); // 构建出lst_channel
    channel.set_read_callback(std::bind(Accept, &Loop, std::ref(channel)));
    channel.enAbleread(); // lst_channel开启读监控了
    // 现在的问题就是close delete channel之后，a->HandleEvent()还在继续调用导致问题
    while (1)
    {
        Loop.Start();
    }
    listen_socket.Close();
}
/// poller内部保存了所有channel，就绪的channel可以直接调用自己内部的HandleEvent

